package xin.marcher.module.search.repository;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.xcontent.XContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import xin.marcher.module.common.core.PageResult;
import xin.marcher.module.search.domain.dto.CompletionSearchWordDTO;
import xin.marcher.module.search.domain.dto.CompletionSearchWordResultDTO;
import xin.marcher.module.search.domain.request.CompletionSearchWordRequest;
import xin.marcher.module.search.domain.request.QueryCompletionSearchWordPageRequest;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 *
 */
@Repository
public class CompletionSearchWordRepository {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    /**
     * 保存补全词
     * https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-document-bulk.html
     */
    public CompletionSearchWordResultDTO saveCompletionSearchWord(CompletionSearchWordRequest request) throws IOException {
        BulkRequest bulkRequest = new BulkRequest(request.getIndexName());

        List<String> completionSearchWords = request.getCompletionSearchWords();
        for (String completionSearchWord : completionSearchWords) {
            bulkRequest.add(new IndexRequest().source(XContentType.JSON, request.getFieldName(), completionSearchWord));
        }

        restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        return new CompletionSearchWordResultDTO(true);
    }

    /**
     * 查询补全词
     */
    public PageResult<CompletionSearchWordDTO> listCompletionSearchWordPage(QueryCompletionSearchWordPageRequest request) throws IOException {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        if (StringUtils.isNotBlank(request.getCompletionSearchWord())) {
            searchSourceBuilder.query(QueryBuilders.matchQuery(request.getFieldName(), request.getCompletionSearchWord()));
        }

        int from = (request.getPageNum() - 1) * request.getPageSize();
        searchSourceBuilder.from(from);
        searchSourceBuilder.size(request.getPageSize());

        SearchRequest searchRequest = new SearchRequest(request.getIndexName());
        searchRequest.source(searchSourceBuilder);

        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        PageResult<CompletionSearchWordDTO> pageResult = new PageResult<>();
        List<CompletionSearchWordDTO> pageContent = new ArrayList<>();
        SearchHit[] hits = searchResponse.getHits().getHits();
        for (SearchHit hit : hits) {
            pageContent.add(new CompletionSearchWordDTO(((String) hit.getSourceAsMap().get(request.getFieldName()))));
        }
        pageResult.setContent(pageContent);
        pageResult.setTotalElements(searchResponse.getHits().getTotalHits().value);
        pageResult.setSize(request.getPageSize());
        pageResult.setNumber(request.getPageNum());
        return pageResult;
    }
}
